import Legend from '@/components/geo-map/common-map-legend'

import { mapState } from 'vuex'

export default {
  data () {
    return {
      layersLoaded: false
    }
  },
  components: {
    Legend
  },
  computed: {
    ...mapState('map', ['initLayerZIndexMap'])
  },
  methods: {
    async getMapData (callback) {
      // const promiseList = []
      // const keyList = []
      this.$mapManager.invoke('clearSelectStyle')
      for (const key in this.metaSetMap) {
        if (Object.hasOwnProperty.call(this.metaSetMap, key)) {
          const metaSet = this.metaSetMap[key]
          const methodCode = this.methodCodeMap ? this.methodCodeMap[key] || 'select' : 'select'
          const methodParams = this.methodParamsMap ? this.methodParamsMap[key] || null : null
          // if (this.firstLoaded) {
          //   if (!this.searchLayers.includes(key)) {
          //     continue
          //   }
          //   promiseList.push(this.getGeoByMetaSet(metaSet, methodCode, methodParams))
          //   keyList.push(key)
          // } else {
          //   if (!this.searchLayers.includes(key)) {
          //     await this.clearLayerById(key)
          //     continue
          //   }
          //   promiseList.push(this.getGeoByMetaSet(metaSet, methodCode, methodParams))
          //   keyList.push(key)
          // }
          if (this.firstLoaded.includes(key)) {
            if (!this.searchLayers.includes(key)) {
              this.needClearLayer && this.needClearLayer.includes(key) && await this.clearLayerById(key)
              continue
            }
          } else {
            this.firstLoaded.push(key)
          }
          let data = await this.getGeoByMetaSet(metaSet, methodCode, methodParams)
          const keys = this.resultKey ? this.resultKey[key] : null
          data = data.filter(item => (keys ? (item[keys[0]] || item[keys]) : item.RES_X) && (keys ? (item[keys[1]] || item[keys]) : item.RES_Y))
          // 清空当前图层
          await this.clearLayerById(key)
          if (data.length < 1000) {
            this.renderMapData(data, key)
          } else {
            for (let i = 0; i < data.length; i = i + 1000) {
              this.renderMapData(data.slice(i, i + 1000), key)
            }
          }
        }
      }
      // const arr = await Promise.all(promiseList)

      // for (let i = 0; i < arr.length; i++) {
      //   const keys = this.resultKey ? this.resultKey[keyList[i]] : null
      //   let data = arr[i]
      //   data = data.filter(item => (keys ? (item[keys[0]] || item[keys]) : item.RES_X) && (keys ? (item[keys[1]] || item[keys]) : item.RES_Y))
      //   await this.renderMapData(data, keyList[i])
      // }
      callback && callback()
    },
    async getGeoByMetaSet (metaSet, methodCode, methodParams) {
      const { rows } = await this.$request.singleTableOperation({
        url: '/grid/getTableData',
        metaSet,
        methodCode,
        methodParams: methodParams || undefined
      })
      return rows
    },
    async renderMapData (rows, layerId) {
      const layer = await this.$mapManager.invokeUtils('getLayer', layerId)
      const features = []
      for (const row of rows) {
        const keys = this.resultKey ? this.resultKey[layerId] : null
        if (typeof keys === 'string' && row[keys]) {
          // 矢量文件特殊处理
          const feature = await this.$mapManager.invoke('transfromFeature', row[keys])
          const l = this.legends.find(item => item.layerId === layerId)
          // feature.set('selectStyle', this.selectStyle, true)
          feature.set('fillColor', l.fillColor, true)
          feature.set('color', l.color, true)
          feature.setId(row.BYTJCGID)
          feature.setStyle(this.vectorStyle)
          feature.setProperties(Object.assign(row, { layerId }))
          layer.getSource().addFeature(feature)
          continue
        }
        const point = this.$mapManager.getMapComponent().map1.bkol.getPoint(keys ? row[keys[0]] : row.RES_X, keys ? row[keys[1]] : row.RES_Y)
        const feature = new window.ol.Feature(point)
        const img = layerId.endsWith('_cluster') ? layerId.split('_')[0] : layerId
        const style = this.getStyleByLayerId(img, layerId, row)
        feature.setProperties(Object.assign({ img: require(`@/assets/images/map/point-${img}.png`) }, row, { layerId }))
        if (layer.get('hasText')) {
          feature.set('normalStyle', style)
          const text = row[layer.get('textKey')]
          feature.set('textStyle', new window.ol.style.Style({
            text: new window.ol.style.Text({
              font: 'bold 14px sans-serif',
              text: text,
              fill: new window.ol.style.Fill({
                color: 'white'
              }),
              stroke: new window.ol.style.Stroke({
                color: '#333',
                width: 2
              }),
              offsetY: 20
            })
          }))
        }
        feature.setStyle(style)
        features.push(feature)
      }
      layer.getSource().addFeatures(features)
      if (layer.get('hasCluster')) {
        await this.$mapManager.invoke('renderClusterLayer', layerId, features)
      }
    },
    getStyleByLayerId (img, layerId, row) {
      const iconOption = new window.ol.style.Icon({
        offset: [0, 0],
        opacity: 1,
        scale: 0.8,
        src: require(`@/assets/images/map/point-${img}.png`),
        size: [58, 200]
      })
      const option = { image: iconOption }
      // if (layerId && layerId === 'photo' && row.RES_DIRECTION) {
      //   // 照片图层的特殊处理
      //   const styles = [new window.ol.style.Style(option)]
      //   styles.push(new window.ol.style.Style({
      //     image: new window.ol.style.Icon({
      //       src: require('@/assets/images/map/photo-arrow.png'),
      //       anchor: [0.5, 1],
      //       rotation: (parseFloat(row.RES_DIRECTION) - 1) * Math.PI / 6
      //     })
      //   }))
      //   return styles
      // }
      return new window.ol.style.Style(option)
    },
    async clearLayerById (layerId) {
      const layer = await this.$mapManager.invokeUtils('getLayer', layerId)
      if (layer) {
        layer.getSource().clear()
        if (layer.get('hasCluster')) {
          const clusterLayer = await this.$mapManager.invokeUtils('getLayer', layerId + '_cluster')
          // 聚合图层需要get两次
          if (clusterLayer) {
            clusterLayer.getSource().getSource().clear()
          }
        }
      } else {
        console.error('图层' + layerId + '不存在')
      }
    },
    clearAllLayers () {
      this.$mapManager.invoke('clearSelectStyle')
      this.legends.forEach(item => {
        this.clearLayerById(item.layerId)
      })
    },
    async createLayers (callback) {
      // 恢复到全貌
      setTimeout(() => {
        this.$mapManager.invoke('setZoom', 'quanmao')
      }, 200)
      const layers = this.legends.map(item => ({
        bklayerGroupId: item.groupName,
        bklayerId: item.layerId,
        bklayerName: item.name,
        bklayerType: 'vectorlayer_empty',
        bklayerSn: this.initLayerZIndexMap[item.layerId],
        clusterSn: this.initLayerZIndexMap[item.layerId + '_cluster'],
        visible: item.visible ?? true,
        needCluster: item.needCluster ?? false,
        hasText: item.hasText ?? false,
        textKey: item.textKey,
        isClick: item.isClick ?? false,
        isHover: item.isHover ?? false,
        declutter: ['dnpj', 'bcxs', 'scyl'].includes(item.layerId)
      }))
      await this.$mapManager.invoke('addLayers', layers)
      this.layersLoaded = true
    },
    vectorStyle (feature) {
      const color = feature.get('color')
      const properties = feature.getProperties()
      const styles = []
      const ol = window.ol
      const fillColor = feature.get('fillColor').split(',')
      fillColor.push(0.2)
      styles.push(new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: color,
          width: 2
        }),
        fill: new ol.style.Fill({
          color: fillColor
        }),
        image: new ol.style.Circle({
          radius: 4,
          fill: new ol.style.Fill({
            color: '#ffff'
          }),
          stroke: new ol.style.Stroke({
            color: color,
            width: 2
          })
        })
      }))
      if (['dnpj', 'bcxs'].includes(properties.layerId)) {
        const first = feature.getGeometry().getFirstCoordinate()
        const last = feature.getGeometry().getLastCoordinate()

        styles.push(new ol.style.Style({
          geometry: new window.ol.geom.MultiPoint([first, last]),
          text: new window.ol.style.Text({
            font: 'bold 14px sans-serif',
            text: properties.TZZL.toString(), // 特征值量
            fill: new window.ol.style.Fill({
              color: 'white'
            }),
            stroke: new window.ol.style.Stroke({
              color: color,
              width: 2
            }),
            overflow: true
          })
        }))
      }
      if (properties.layerId === 'scyl') {
        styles.push(new ol.style.Style({
          text: new window.ol.style.Text({
            font: 'bold 12px sans-serif',
            text: properties.TZZL.toString() + 'mm\n' + properties.SCYLRQ, // 特征值量
            fill: new window.ol.style.Fill({
              color: 'white'
            }),
            stroke: new window.ol.style.Stroke({
              color: '#333',
              width: 2
            }),
            overflow: true,
            offsetY: 30
          })
        }))
      }
      return styles
    },
    selectStyle (feature) {
      const type = feature.getGeometry().getType()
      // const layerId = feature.getProperties().layerId
      switch (type) {
        case 'Point':
          {
            const style = new window.ol.style.Style({
              image: new window.ol.style.Circle({
                radius: 6,
                fill: new window.ol.style.Fill({
                  color: '#ffffff'
                }),
                stroke: new window.ol.style.Stroke({
                  color: feature.get('color'),
                  width: 2
                })
              })
            })
            feature.setStyle(style)
          }
          break
        case 'LineString':
          {
            // const colors = {
            //   dnpj: ['#e04545', '#ff3d00', '#FFCDD2'],
            //   bcxs: ['#1cb55b', '#ff8f00', '#FFECB3'],
            //   scyl: ['#e04545', '#00c853', '#B9F6CA']
            // }
            const lineStyle = new window.ol.style.Style({
              stroke: new window.ol.style.Stroke({
                // color: colors[layerId][0],
                color: feature.get('color'),
                width: 2
              // lineDash: [10, 8] // 示例虚线模式：10px实线、8px空白
              })
            })
            feature.setStyle(lineStyle)
            // let dashOffset = 0

            let i = 0
            let isAdd = true
            window.mapSelectTimer && clearInterval(window.mapSelectTimer)
            window.mapSelectTimer = setInterval(() => {
            // dashOffset = (dashOffset + 1) % 17 // 更新偏移量，循环17次（等于虚线模式两倍长度 + 1）
            // lineStyle.getStroke().setLineDashOffset(dashOffset)
              if (isAdd) {
                i++
                if (i >= 8) {
                  isAdd = false
                }
              } else {
                i--
                if (i <= 0) {
                  isAdd = true
                }
              }
              console.log(i)
              // lineStyle.getStroke().setColor(colors[layerId][i % colors[layerId].length])
              const fillColor = feature.get('fillColor').split(',')
              fillColor.push(1 - (0.1 * i))
              lineStyle.getStroke().setColor(fillColor)
              feature.changed() // 触发样式更新
            }, 50) // 调整以改变流动速度
          }
          break
        case 'Polygon':
          {
            const fillColor = feature.get('fillColor').split(',')
            fillColor.push(0.6)
            const style = new window.ol.style.Style({
              fill: new window.ol.style.Fill({
                color: fillColor
              }),
              stroke: new window.ol.style.Stroke({
                color: feature.get('color'),
                width: 2
              })
            })
            feature.setStyle(style)
          }
          break
      }
    }
  }
}
